package com.ihg.hiex.admin.handler.impl;

import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ihg.hiex.admin.handler.AccountUploadHandler;
import com.ihg.hiex.entity.user.Assessor;
import com.ihg.hiex.entity.user.Delegate;

/**
 * 
 * @author dan
 *
 */
@Component("accountUploadHandler")
public class AccountUploadHandlerImpl implements AccountUploadHandler{
    
    private static final Logger logger = LoggerFactory.getLogger(AccountUploadHandlerImpl.class);

    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.handler.AccountUploadHandler#assessorUpload(java.io.InputStream)
     */
    @SuppressWarnings("unchecked")
    public List<Assessor> assessorUpload(InputStream inputStream) {
        List<Assessor> assessors = (List<Assessor>) this.parse(inputStream, true);
        return assessors;
    }

    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.handler.AccountUploadHandler#delegateUpload(java.io.InputStream)
     */
    @SuppressWarnings("unchecked")
    public List<Delegate> delegateUpload(InputStream inputStream) {
        List<Delegate> delegates = (List<Delegate>) this.parse(inputStream, false);
        return delegates;
    }
    
    /**
     * 
     * @param inputStream
     * @param isAssessor
     * @return
     */
    private Object parse(InputStream inputStream, boolean isAssessor) {
        
        // 0. prepare data
        List<Object> result = new LinkedList<Object>();
        DataFormatter formatter = new DataFormatter();
        
        try {
            
            logger.trace("#parse() - Starting parsing upload file.");

            // 1. get workbook
            Workbook workbook = WorkbookFactory.create(inputStream);
            
            // 2. get sheet and rows
            Sheet sheet = workbook.getSheetAt(0);
            Iterator<Row> rows = sheet.iterator();
            
            while (rows.hasNext()) {
                
                Row row = rows.next();
                int rowNum = row.getRowNum();
                
                if (rowNum <= 1) {
                    continue;
                }
                
                // constructor assessor or delegate
                if(isAssessor) {
                    Assessor assessor = this.initAssessor(formatter, row);
                    if(assessor != null) {
                        result.add(assessor);
                    }
                } else {
                    Delegate delegate = this.initDelegate(formatter, row);
                    if(delegate != null) {
                        result.add(delegate);
                    }
                }
                
            }
            
            logger.trace("#parse() - Finishing parsing file with {} records.", result.size());
            
        } catch (Exception e) {
            logger.error("#parse() - Finishing parsing file with errors.", e);
        }
        
        return result;
        
    }
    
    /**
     * construct assessor by excel formatter
     * 
     * @param formatter
     * @param row
     * @return
     */
    private Assessor initAssessor(DataFormatter formatter, Row row) {
        
        // construct assessor
        String name = formatter.formatCellValue(row.getCell(0));
        String email = formatter.formatCellValue(row.getCell(1));
        String telephone = formatter.formatCellValue(row.getCell(2));
        String hotelName = formatter.formatCellValue(row.getCell(3));
        String subregion = formatter.formatCellValue(row.getCell(4));
        String title = formatter.formatCellValue(row.getCell(5));
        
        if(StringUtils.isBlank(email)) {
            return null;
        } else {
            return new Assessor(name, email, telephone, hotelName, subregion, title);
        }
        
    }
    
    /**
     * construct delegate by excel formatter
     * 
     * @param formatter
     * @param row
     * @return
     */
    private Delegate initDelegate(DataFormatter formatter, Row row) {
        
        // construct assessor
        String name = formatter.formatCellValue(row.getCell(0));
        String email = formatter.formatCellValue(row.getCell(1));
        String telephone = formatter.formatCellValue(row.getCell(2));
        String hotelName = formatter.formatCellValue(row.getCell(3));
        String subRegion = formatter.formatCellValue(row.getCell(4));
        String currentJobTitle = formatter.formatCellValue(row.getCell(5)); // currentJobTitle
        String lineManager = formatter.formatCellValue(row.getCell(6));     // line manager
        String lineManagerEmail = formatter.formatCellValue(row.getCell(7)); // line manager email
        String targetPosition = formatter.formatCellValue(row.getCell(8));
        String region = formatter.formatCellValue(row.getCell(9));
        String city = formatter.formatCellValue(row.getCell(10));
        
        if(StringUtils.isBlank(email)) {
            return null;
        } else {
            return new Delegate(name, email, telephone, hotelName, subRegion, currentJobTitle, lineManager, lineManagerEmail, targetPosition, region, city);
        }
        
    }

}
